package com.yang.crawler.article.strategy;


import com.gargoylesoftware.htmlunit.html.*;
import com.yang.crawler.file.IFileUploader;
import com.yang.crawler.html.AbstractHtmlUnitTemplate;
import com.yang.crawler.strategy.IArticleCrawlStrategy;
import com.yang.crawler.strategy.annotations.ArticleCrawlStrategy;
import com.yang.crawler.strategy.dto.ArticleColumnCrawlDTO;
import com.yang.crawler.strategy.dto.ArticleCrawlDTO;
import com.yang.crawler.strategy.enums.ArticleCrawlWebsiteEnum;
import com.yang.crawler.strategy.request.ArticleColumnCrawlRequest;
import com.yang.crawler.strategy.request.ArticleCrawlRequest;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

@Component
@ArticleCrawlStrategy(website = ArticleCrawlWebsiteEnum.LEARN_LIANGLIANG_LEE)
public class LearnLiangLiangLeeStrategy implements IArticleCrawlStrategy {
    @Resource
    private IFileUploader localFileUploader;

    @Override
    public ArticleColumnCrawlDTO crawlArticleColumn(ArticleColumnCrawlRequest articleColumnCrawlRequest) {
        String columnUrl = articleColumnCrawlRequest.getColumnUrl();
        return new AbstractHtmlUnitTemplate<ArticleColumnCrawlDTO>(columnUrl) {
            @Override
            public ArticleColumnCrawlDTO handleHtmlPage(HtmlPage page) {
                ArticleColumnCrawlDTO articleColumnCrawlDTO = new ArticleColumnCrawlDTO();
                articleColumnCrawlDTO.setTitle(page.getTitleText());
                articleColumnCrawlDTO.setUrl(page.getBaseURI().toString());
                articleColumnCrawlDTO.setProtocol(page.getBaseURL().getProtocol());
                articleColumnCrawlDTO.setWebsite(page.getBaseURL().getHost());

                String xPath = "/html/body/div/div[3]/div[1]/div/div[2]/div[1]/div[2]/ul";
                HtmlUnorderedList articleList = page.getFirstByXPath(xPath);

                String preUrl = page.getBaseURL().getProtocol() + "://" + page.getBaseURL().getHost();
                for (DomElement child : articleList.getChildElements()) {
                    String articleTitle = child.getTextContent();
                    String articleLink = "";
                    if (child.getFirstChild() != null) {
                        HtmlAnchor firstChild = (HtmlAnchor) child.getFirstChild();
                        articleLink = preUrl + firstChild.getHrefAttribute();
                    }
                    articleColumnCrawlDTO.putTitleAndLink(articleTitle, articleLink);
                }
                return articleColumnCrawlDTO;
            }
        }.reptile();
    }

    @Override
    public ArticleCrawlDTO crawlArticle(ArticleCrawlRequest articleCrawlRequest) {
        String columnTitle = articleCrawlRequest.getColumnTitle();
        String website = articleCrawlRequest.getWebsite();
        String articleUrl = articleCrawlRequest.getArticleUrl();

        return new AbstractHtmlUnitTemplate<ArticleCrawlDTO>(articleUrl) {
            @Override
            public ArticleCrawlDTO handleHtmlPage(HtmlPage page) {
                ArticleCrawlDTO articleCrawlDTO = new ArticleCrawlDTO();
                articleCrawlDTO.setLink(articleUrl);
                articleCrawlDTO.setTitle(page.getTitleText());

                HtmlDivision htmlDivision = page.getFirstByXPath("/html/body/div/div[3]/div[1]/div/div[2]/div[1]/div[2]");
                for (DomElement childElement : htmlDivision.getChildElements()) {
                    if (childElement instanceof HtmlParagraph) {
                        HtmlParagraph paragraph = (HtmlParagraph) childElement;
                        DomNodeList<HtmlElement> imgElements = paragraph.getElementsByTagName("img");
                        if (!imgElements.isEmpty()) {
                            for (HtmlElement imgElement : imgElements) {
                                HtmlImage image = (HtmlImage) imgElement;
                                String srcAttribute = image.getSrcAttribute();
                                String filename = srcAttribute.substring(srcAttribute.lastIndexOf("/") + 1);
                                String directory = website + File.separator + columnTitle + File.separator + articleCrawlDTO.getTitle();
                                String imgPath = storeImage(directory, filename, image);
                                image.setAttribute("src", imgPath);
                            }
                        }
                    }
                }
                StringBuilder html = new StringBuilder();
                html.append("<html><head><meta charset=\"UTF-8\">");
                html.append("<style>");
                html.append("img{");
                html.append("max-width:100%;height:auto;}");
                html.append("</style>");
                html.append("</head>");
                html.append("<body>");
                html.append(htmlDivision.asXml());
                html.append("</body></html>");
                articleCrawlDTO.setHtmlContent(html.toString());
                return articleCrawlDTO;
            }
        }.reptile();
    }

    private String storeImage(String directory, String filename, HtmlImage image) {
        directory = "image" + File.separator + directory;
        try (InputStream inputStream = image.getWebResponse(true).getContentAsStream()) {
            return localFileUploader.uploadFile(directory, filename, inputStream);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

